package com.mrdeer.server;

import io.netty.channel.*;

import java.net.InetAddress;
import java.util.Date;

/**
 * SimpleChannelInBoundHandler：会在接收到数据之后自动release掉数据占用的Bytebuffer资源，并且继承该类需要指定数据格式
 * ChannelInboundHandlerAdapter: 不会自动释放，需要手动调用ReferenceCountUtil.release()进行释放。
 * <p>
 * 推荐服务端继承ChannelInboundHandlerAdapter，手动进行释放，防止数据未处理完就自动释放了。而且服务端可能有多个客户端进行连接，并且每一个客户端请求的数据格式都不一致，这时便可以进行相应的处理。
 * <p>
 * 客户端根据情况可以集成SimpleChannelInboundHandler类,好处是直接指定好传输的数据格式，就不需要再进行格式的转换了
 *
 * @author ：xie jianchu
 * @date ：Created in 2020/9/25 0025 10:53
 */
@ChannelHandler.Sharable
public class ServerHandler extends SimpleChannelInboundHandler<String> {

    /**
     * 建立连接时，发送一条庆祝消息
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //为新连接发送庆祝
        ctx.write("Welcome to " + InetAddress.getLocalHost().getHostName() + "!\r\n");
        ctx.write("It is " + new Date() + " now .\r\n");
        ctx.flush();
    }

    /**
     * 业务逻辑处理
     *
     * @param ctx
     * @param request
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String request) throws Exception {
        // Generate and write a response
        String response;
        boolean close = false;
        if (request.isEmpty()) {
            response = "Please type something .\r\n";
        } else if ("bye".equals(request.toLowerCase())) {
            response = "Have a good day!\r\n";
            close = true;
        } else {
            response = "Did you say '" + request + "'";
        }
        ChannelFuture future = ctx.write(response);
        if (close) {
            future.addListener(ChannelFutureListener.CLOSE);
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    /**
     * 异常处理
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
